using System;
using System.Collections.Generic;
using System.Text;

namespace System.Collections.Generic
{
	public class ItemAtEventArgs<T> : EventArgs
	{
		public readonly T Item;
		public readonly int Index;
		public ItemAtEventArgs(T item, int index) { Item = item; Index = index; }
		public override string ToString()
		{
			return String.Format("(ItemAtEventArgs {0} '{1}')", Index, Item);
		}
	}

	public class ItemRangeEventArgs<T> : EventArgs
	{
		public readonly T[] Items;
		public readonly int Index, Count;
		public ItemRangeEventArgs(T[] items, int index, int count) { Items = items; Index = index; Count = count; }
		public override string ToString()
		{
			return String.Format("(ItemRangeEventArgs {0} Cnt: {2})", Index, Items, Count);
		}
	}

	public class EventedList<T> : List<T>
	{
		public EventedList() : base() { }
		public EventedList(int capacity) : base(capacity) { }
		public EventedList(IEnumerable<T> collection) : base(collection) { }

		public event ItemInsertedHandler ItemInserted;
		public event ItemRemovedHandler ItemRemoved;
		public event ItemRangeInsertedHandler ItemRangeInserted;
		public event ItemRangeRemovedHandler ItemRangeRemoved;

		public delegate void ItemInsertedHandler(object sender, ItemAtEventArgs<T> e);
		public delegate void ItemRemovedHandler(object sender, ItemAtEventArgs<T> e);
		public delegate void ItemRangeInsertedHandler(object sender, ItemRangeEventArgs<T> e);
		public delegate void ItemRangeRemovedHandler(object sender, ItemRangeEventArgs<T> e);

		protected virtual void OnItemRemoved(ItemAtEventArgs<T> e)
		{
			ItemRemovedHandler handler1 = this.ItemRemoved;
			if (handler1 != null)
				handler1(this, e);
		}

		protected virtual void OnItemInserted(ItemAtEventArgs<T> e)
		{
			ItemInsertedHandler handler1 = this.ItemInserted;
			if (handler1 != null)
				handler1(this, e);
		}

		protected virtual void OnItemRangeRemoved(ItemRangeEventArgs<T> e)
		{
			ItemRangeRemovedHandler handler1 = this.ItemRangeRemoved;
			if (handler1 != null)
				handler1(this, e);
		}

		protected virtual void OnItemRangeInserted(ItemRangeEventArgs<T> e)
		{
			ItemRangeInsertedHandler handler1 = this.ItemRangeInserted;
			if (handler1 != null)
				handler1(this, e);
		}

		public new void Add(T item)
		{
			base.Add(item);
			OnItemInserted(new ItemAtEventArgs<T>(item, base.Count - 1));
		}

		public new void AddRange(IEnumerable<T> collection)
		{
			this.InsertRange(base.Count, collection);
		}

		public new void Insert(int index, T item)
		{
			base.Insert(index, item);
			OnItemInserted(new ItemAtEventArgs<T>(item, index));
		}

		public new void InsertRange(int index, IEnumerable<T> collection)
		{
			int count = base.Count;
			base.InsertRange(index, collection);
			count = base.Count - count;
			OnItemRangeInserted(new ItemRangeEventArgs<T>(base.GetRange(index, count).ToArray(), index, count));
		}

		public new bool Remove(T item)
		{
			int num1 = base.IndexOf(item);
			if (num1 >= 0)
			{
				this.RemoveAt(num1);
				return true;
			}
			return false;
		}

		public new void RemoveAt(int index)
		{
			T item = base[index];
			base.RemoveAt(index);
			OnItemRemoved(new ItemAtEventArgs<T>(item, index));
		}

		public new void RemoveRange(int index, int count)
		{
			List<T> rc = base.GetRange(index, count);
			base.RemoveRange(index, count);
			OnItemRangeRemoved(new ItemRangeEventArgs<T>(rc.ToArray(), index, count));
		}
	}
}